package com.recharge.sup.impl;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.recharge.OrderService;
import com.recharge.domain.TradeFlow;
import com.recharge.domain.TradeOrder;
import com.recharge.mapper.IProvinceMapper;
import com.recharge.mapper.ITradeOrderMapper;
import com.recharge.mapper.ITradeSupProductInfoMapper;
import com.recharge.sup.AbsSupChargeService;
import com.recharge.utils.HttpClientUtils;
import com.recharge.utils.ProcessResult;
import com.recharge.utils.ResultCodeQuXun;


/**
 * 千米对接
 * @author qq
 *
 */
@Service
public class QianMiChargeServiceImpl extends AbsSupChargeService{
	
	@Value("${qianmi.sendFlowUrl}")
    private  String sendFlowUrl ;
	
	@Value("${qianmi.methodQueryProduct}")
    private  String methodQueryProduct ;
	
	@Value("${qianmi.methodRecharge}")
    private  String methodRecharge ;
	
	@Value("${qianmi.methodBill}")
    private  String methodBill ;
	
	@Value("${qianmi.methodQueryOrder}")
    private  String methodQueryOrder ;
	
	@Value("${qianmi.format}")
    private  String format ;
	
	@Value("${qianmi.appKey}")
    private  String appKey ;
	
	@Value("${qianmi.appSecret}")
    private  String appSecret ;
	
	@Value("${qianmi.access_token}")
    private  String access_token ;
	
	@Value("${qianmi.v}")
    private  String v ;
	
	
	@Autowired
    private OrderService orderService;
    
    @Autowired
    private IProvinceMapper iProvinceMapper;
    
    @Autowired
    private ITradeOrderMapper iTradeOrderMapper;
    
   
    private Logger logger = LoggerFactory.getLogger(getClass());
    
	@Override
	public ProcessResult recharge(TradeOrder tradeOrder, TradeFlow tradeFlow) {
		String orderId = tradeOrder.getOrderId();       //订单id
		String mobileNo = tradeOrder.getChargeNumber(); //手机号
		String flow = tradeOrder.getChargeMoney()+"M"; //流量值
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String timestamp = sdf.format(new Date());  //时间戳
		
		String sginq = "";  //查询产品签名
		String sginS = "";  //发送订单签名
		String sginR = "";  //发送重值签名
		String resultQuery = "";//查询返回集
		String resultSend = ""; //订单返回集
		String resultBill = ""; //充值返回集
		String itemId = ""; //产品编号
		String billId = ""; //商户订单号
		
//		查询商品
		String stringSign = appSecret+"access_token"+access_token+"appKey"+appKey
				+"flow"+flow+"format"+format+"method"+methodQueryProduct+"mobileNo"+mobileNo
				+"timestamp"+timestamp+"v"+v+appSecret;
		logger.info("查询千米商品sign:{}", stringSign);
		try {
			sginq = sha1(stringSign);
		} catch (IOException e) {
			e.printStackTrace();
		}
		Map<String,String> mapq = new HashMap<String, String>();
		mapq.put("access_token",access_token);
		mapq.put("appKey", appKey);
		mapq.put("format", format);
		mapq.put("flow", flow);
		mapq.put("method", methodQueryProduct);
		mapq.put("mobileNo", mobileNo);
		mapq.put("timestamp", timestamp);
		mapq.put("v", v);
		mapq.put("sign", sginq);
		try {
			 resultQuery = HttpClientUtils.invokePostHttp(sendFlowUrl, mapq, "UTF-8", 3000);	 
			 logger.info("查询千米商品result:{}", resultQuery);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Map<String,String> queryProduct = resultItemId(resultQuery);//获取
		itemId = queryProduct.get("itemId");
		if(itemId != null){
			logger.info("查询到千米商品id:{}", itemId);
		}else if(itemId == null){
			String code = queryProduct.get("code");
			String message = queryProduct.get("message");
			logger.info("查询千米商品错误code：{}message:{}",code, message );
			ProcessResult processResult = new ProcessResult();
			iTradeOrderMapper.updateProcessStatus(orderId,message);
			processResult.setCode(ProcessResult.FAIL);
			return processResult;
		}
		
//		发送并生成订单
		String sendSign = appSecret+"access_token"+access_token+"appKey"+appKey
				+"format"+format+"itemId"+itemId+"method"+methodRecharge+"mobileNo"+mobileNo
				+"timestamp"+timestamp+"v"+v+appSecret;
		logger.info("发送千米订单sendSign:{}",sendSign);
		try {
			sginS = sha1(sendSign);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Map<String,String> maps = new HashMap<String, String>();
		maps.put("access_token",access_token);
		maps.put("appKey", appKey);
		maps.put("format", format);
		maps.put("itemId", itemId);
		maps.put("method", methodRecharge);
		maps.put("mobileNo",mobileNo );
		maps.put("timestamp", timestamp);
		maps.put("v", v);
		maps.put("sign", sginS);
		try {
			resultSend = HttpClientUtils.invokePostHttp(sendFlowUrl, maps, "UTF-8", 3000);
			logger.info("发送千米订单返回resultSend:{}",resultSend);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Map<String,String> sendProduct = resultSend(resultSend);
		String sendCode = sendProduct.get("rechargeState");
		if(sendCode != null){
			ProcessResult processResult = new ProcessResult();
			if("0".equals(sendCode)){
				 billId = sendProduct.get("billId");
				 iTradeOrderMapper.updateMerOrderId(orderId, billId);//修改订单表为商户id为订单编号
				 logger.info("返回千米订单正在充值中");
			}else if("1".equals(sendCode)){
				 billId = sendProduct.get("billId");  //获取订单编号
				 iTradeOrderMapper.updateMerOrderId(orderId, billId);//修改订单表为商户id为订单编号
				 logger.info("返回千米订单提交成功");
			}else if("9".equals(sendCode)){
				 logger.info("返回千米订单提交撤销");
				 processResult.setCode(ProcessResult.FAIL);   
		         return processResult;
			}
		}else{
			String codeSend = sendProduct.get("code");
			String messagSend = sendProduct.get("message");
			logger.info("发送千米订单错误code：{}message:{}",codeSend, messagSend );
			ProcessResult processResult = new ProcessResult();
			iTradeOrderMapper.updateProcessStatus(orderId,messagSend);
			processResult.setCode(ProcessResult.FAIL);
			return processResult;
		}
		
		
//		充值		
		String rechargeSign = appSecret+"access_token"+access_token+"appKey"+appKey+"billId"+billId
				+"format"+format+"method"+methodBill
				+"timestamp"+timestamp+"v"+v+appSecret;
		logger.info("支付千米订单sign:{}", rechargeSign);
		try {
			sginR = sha1(rechargeSign);
		} catch (IOException e) {
			e.printStackTrace();
		}
		Map<String,String> mapr = new HashMap<String, String>();
		mapr.put("billId", billId);
		mapr.put("access_token",access_token);
		mapr.put("appKey", appKey);
		mapr.put("format", format);
		mapr.put("method", methodBill);
		mapr.put("timestamp", timestamp);
		mapr.put("v", v);
		mapr.put("sign", sginR);
		try {
			resultBill = HttpClientUtils.invokePostHttp(sendFlowUrl, mapr, "UTF-8", 3000);
			logger.info("orderId:{}支付返回结果:{}",orderId ,resultBill);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(resultBill != null && !"".equals(resultBill)){
			Map<String,String> mapB= resultBill(resultBill);
			String status = mapB.get("status");

			if(status != null){
				 logger.info("orderId:{}支付充值成功",orderId);//有值成功的
				 ProcessResult processResult = new ProcessResult();
				 processResult.setCode(ProcessResult.SUCCESS);
				 return processResult;
			}else if(status == null){
				String codeBill = mapB.get("code");
				String messagBill = mapB.get("message");
				logger.info("支付千米订单错误code：{}message:{}",codeBill, messagBill);
				ProcessResult processResult = new ProcessResult();
				iTradeOrderMapper.updateProcessStatus(orderId,messagBill);
				processResult.setCode(ProcessResult.FAIL);
				return processResult;
			}
		}
		iTradeOrderMapper.updateProcessStatus(orderId,"发送支付失败");
	    logger.info("order_id:{}发送结果可疑",orderId );     
        ProcessResult processResult = new ProcessResult();
        processResult.setCode(ProcessResult.UNKNOWN);   
        return processResult;
	}


	/**
	 * 查询订单状态
	 * @param tradeOrder
	 * @param tradeFlow
	 * @return
	 */
	@Override
	public ProcessResult query(TradeOrder tradeOrder, TradeFlow tradeFlow) {
		String orderId = tradeOrder.getOrderId();//订单id
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String timestamp = sdf.format(new Date());  //时间戳
		String billId = tradeOrder.getMerOrderid(); //订单号
		String sgin = "";
		String result = "";
		
		String querySign = appSecret+"access_token"+access_token+"appKey"+appKey+"billId"+billId
				+"format"+format+"method"+methodBill
				+"timestamp"+timestamp+"v"+v+appSecret;
		logger.info("查询千米订单sign:{}", querySign);
		try {
			sgin = sha1(querySign);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Map<String,String> map = new HashMap<String, String>();
		map.put("billId", billId);
		map.put("access_token",access_token);
		map.put("appKey", appKey);
		map.put("format", format);
		map.put("method", methodBill);
		map.put("timestamp", timestamp);
		map.put("v", v);
		map.put("sign", sgin);
		try {
			result = HttpClientUtils.invokePostHttp(sendFlowUrl, map, "UTF-8", 3000);
			logger.info("查询千米返回结果result:{}",result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(result != null && !"".equals(result)){
			Map<String,String> mapB= resultBill(result);
			String status = mapB.get("status");//获取订单状态
			
			if(status != null){
				 logger.info("orderId:{}充值成功",orderId );
				 ProcessResult processResult = new ProcessResult();
				 processResult.setCode(ProcessResult.SUCCESS);
			     return processResult;
			}else if(status == null){
				String codeBill = mapB.get("code");
				String messagBill = mapB.get("message");
				logger.info("查询千米订单code：{}message:{}",codeBill, messagBill);
				ProcessResult processResult = new ProcessResult();
				iTradeOrderMapper.updateProcessStatus(orderId,messagBill);
				processResult.setCode(ProcessResult.FAIL);
				return processResult;
			}
		}
		
	    logger.info("order_id:{}发送结果可疑",orderId );  
	    iTradeOrderMapper.updateProcessStatus(orderId,"查询失败");
        ProcessResult processResult = new ProcessResult();
        processResult.setCode(ProcessResult.UNKNOWN);   
        return processResult;
		
	}
	
	
	@Override
	public void response(TradeOrder tradeOrder, TradeFlow tradeFlow, Map<String, String> responseMap) {
		//实现查询即可
	}

	
	//千米自带的加密方式
	public static String sign(Map<String, String> param, String secret) throws IOException {
        if (param == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        List<String> paramNames = new ArrayList<String>(param.size());
        paramNames.addAll(param.keySet());
        Collections.sort(paramNames);
        sb.append(secret);
        for (String paramName : paramNames) {
            sb.append(paramName).append(param.get(paramName));
        }
        sb.append(secret);
        return sha1(sb.toString());
    }
	//千米自带的加密方式
	public static String sha1(String str) throws IOException {
        return byte2hex(getSHA1Digest(str));
    }
	//千米自带的加密方式
    private static byte[] getSHA1Digest(String data) throws IOException {
        byte[] bytes;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            bytes = md.digest(data.getBytes("utf-8"));
        } catch (GeneralSecurityException gse) {
            throw new IOException(gse);
        }
        return bytes;
    }
    //千米自带的加密方式
    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }
    
    //结果集json转Map
    public static Map<String,String> jsonToObject(String jsonStr){
        Map<String, String> map = new HashMap<String, String>();
        map= (Map<String, String>) JSON.parseObject(jsonStr, HashMap.class);
        return map;
    }
    
    
    /**
     * 处理查询商品结果集
     * @param result
     * @return
     */
    public static Map<String,String> resultItemId(String resultQuery){
    	Map<String, String> itemIdMap = jsonToObject(resultQuery); //json转成map
    	String resultItem = "";
    	String resultTrue =  JSON.toJSONString(itemIdMap.get("mobile_flow_items_list2_response"));
    	//System.out.println("返回为"+resultTrue);
    	String resultFalse = itemIdMap.get("errorToken");
    	//System.out.println("返回为"+resultFalse);
    	if(resultTrue != null && !"null".equals(resultTrue)){
    		itemIdMap = jsonToObject(resultTrue);  //json转成map
    		resultItem = JSON.toJSONString(itemIdMap.get("items"));
    		itemIdMap = jsonToObject(resultItem);  
    		resultItem = JSON.toJSONString(itemIdMap.get("item"));
    		itemIdMap = jsonToObject(JSON.parseArray(resultItem).get(0).toString());//获取数据中的json对象并转成map
    		return itemIdMap;   
    	}else if(resultFalse != null && !"null".equals(resultFalse)){
    		resultItem = JSON.toJSONString(itemIdMap.get("subErrors"));//不符合文档说明,文档上是两层
    		itemIdMap = jsonToObject(JSON.parseArray(resultItem).get(0).toString());
    		return itemIdMap;
    	}
    	return null;
    }
    
    /**
     * 处理发送订单结果集
     * @param result
     * @return
     */
    public static Map<String,String> resultSend(String resultSend){
    	Map<String, String> map = jsonToObject(resultSend); //json转成map
    	String resultItem = "";
    	String resultTrue =  JSON.toJSONString(map.get("mobile_charge_create_bill_response"));
    	String resultFalse = map.get("errorToken");
    	
    	if(resultTrue != null && !"null".equals(resultTrue)){
    		map = jsonToObject(resultTrue);  //json转成map
    		resultItem = JSON.toJSONString(map.get("orderDetailInfo"));
    		map = jsonToObject(resultItem);
    		return map;   
    	}else if(resultFalse != null && !"null".equals(resultFalse)){
    		resultItem = JSON.toJSONString(map.get("subErrors"));//不符合文档说明,文档上是两层
    		map = jsonToObject(JSON.parseArray(resultItem).get(0).toString());
    		return map;
    	}
    	return null;
    }
    
   /**
     * 处理充值订单结果集
     * @param resultBill
     * @return
     */
    public static Map<String,String> resultBill(String resultBill){
    	Map<String, String> map = jsonToObject(resultBill); //json转成map
    	String resultItem = "";
    	String resultTrue =  JSON.toJSONString(map.get("status"));
    	String resultFalse = map.get("errorToken");
    	if(resultTrue != null && !"null".equals(resultTrue)){
    		return map;   
    	}else if(resultFalse != null && !"null".equals(resultFalse)){
    		resultItem = JSON.toJSONString(map.get("subErrors"));//不符合文档说明,文档上是两层
    		map = jsonToObject(JSON.parseArray(resultItem).get(0).toString());
    		return map;
    	}
    	return null;
    }
    
    
    public static void main(String[] args) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String mobileNo = "18351454609";
		String timestamp = sdf.format(new Date());
		//System.out.println(timestamp);
		String flow = "300M";
		String stringSign = "RXB3uxK4wGHy8JPWjcm8RMFsek893JHr"
		+"access_token"+"cef66770032c44df91577b9ca5dc58c2"
		+"appKey"+"10000148"
		+"flow"+"300M"+"format"+"json"+
		"method"+"qianmi.elife.mobile.flow.items.list2"+"mobileNo"+"18351454609"+
		"timestamp"+timestamp+"v"+"1.1"+"RXB3uxK4wGHy8JPWjcm8RMFsek893JHr";
		String sign= sha1(stringSign);
		Map<String,String> map = new HashMap<String, String>();
		map.put("access_token","cef66770032c44df91577b9ca5dc58c2");
		map.put("appKey", "10000148");
		map.put("flow", "300M");
		map.put("format", "json");
		map.put("method", "qianmi.elife.mobile.flow.items.list2");
		map.put("mobileNo", "18351454609");
		map.put("timestamp", timestamp);
		map.put("v", "1.1");
		map.put("sign", sign);
		String result = HttpClientUtils.invokePostHttp("http://gw.api.qianmi.com/api", map, "UTF-8", 3000);
		Map<String,String> queryProduct = resultItemId(result);//获取
		String itemId = queryProduct.get("itemId");
		//System.out.println(result);
	    //String item =resultItemId(result).get("code");
//	    String i = resultItemId(result).get("message");
		 //String item =resultItemId(result).get("itemId");
		 //String i = resultItemId(result).get("message");
	    //item = resultItemId(result);
		//Map<String, String> rspMap = jsonToObject(result);
		
//		String result1 = rspMap.get("errorToken");
//		rspMap = jsonToObject(result1);
//		result1 = JSON.toJSONString(rspMap.get("items"));
//		rspMap = jsonToObject(result1);
//		result1 = JSON.toJSONString(rspMap.get("item"));
//		//System.out.println(JSON.parseArray(result1).toString());
//		rspMap = jsonToObject(JSON.parseArray(result1).get(0).toString());
//		System.out.println(rspMap.get("itemId"));
//		System.out.println(JSON.parseArray(result1));
		//System.out.println(i);
		//System.out.println("返回参数"+item);
		//System.out.println(j);
	}
}
